package com.fnd.servicechat.ws.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.fnd.servicechat.ws.messaging.SendMessage;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description websocket连接基本处理类
 * @Author Administrator
 * @Date 2019/11/15 13:02
 * @Version 1.0
 */
public abstract class BaseWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    private Logger logger = LoggerFactory.getLogger(BaseWebSocketHandler.class);

    //客户端与服务端创建连接的时候调用
    @Override
    public void channelActive (ChannelHandlerContext context)throws Exception{
        logger.debug("客户端{" + context.channel().id().asLongText() + "}与服务端连接开启");
    }
    //客户端与服务端断开连接的时候调用
    @Override
    public void channelInactive(ChannelHandlerContext context)throws Exception{
        logger.debug("客户端{" + context.channel().id().asLongText() + "}与服务端连接断开");
        shutdownChannel(context.channel().id().asLongText());
    }
    //工程出现异常的时候调用
    @Override
    public void exceptionCaught(ChannelHandlerContext context, Throwable throwable)throws Exception{
        throwable.printStackTrace();
        shutdownChannel(context.channel().id().asLongText());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext context, TextWebSocketFrame msg) throws Exception {
        if(msg instanceof FullHttpRequest){
            // http:///
            shutdownChannel(context.channel().id().asLongText());
        }else if (msg instanceof WebSocketFrame){
            //ws://xxxx
//            onMessage(JSON.toJavaObject(JSONObject.parseObject(msg.text()), SendMessage.class), context.channel());
            onMessage(JSON.parseObject(msg.text(), new TypeReference<SendMessage<String>>(){}), context.channel());
        }else{
            shutdownChannel(context.channel().id().asLongText());
        }
    }

    /**
     * 消息处理
     * @param message 服务端接收到的消息
     * @param channel channel
     */
    protected abstract void onMessage(SendMessage message, Channel channel);

    /**
     * 关闭会话
     * @param clientId channel的会话id
     */
    protected abstract void shutdownChannel(String clientId);
}
